#if UNITY_EDITOR && DEBUG_BEHAVIOUR_TREE
#define DEBUG_TREE
#endif
using System.Linq;

namespace GameToolkit.BehaviourTree
{
    /// <summary>
    /// 行为树行为节点
    /// </summary>
    public abstract partial class ActionNode : ExecutableEntry
    {
        IExecutableUpdateCallback[] mUpdates;
        internal override void InitializeSelf(CreateBehaviourTreeContext context)
        {
            base.InitializeSelf(context);
            mUpdates = context.updateBuffer.Count > 0 ? context.updateBuffer.ToArray() : null;
        }

        internal void InvokeOnUpdate(BehaviourTreePlayer player)
        {
            var stat = OnUpdate(player);
            if (stat == NodeState.Running)
            {
                var size = mUpdates == null ? 0 : mUpdates.Length;
                for (int i = 0; i < size; i++)
                {
                    mUpdates[i].OnUpdate(player, this);
#if DEBUG_TREE
                    var add = player.AddActiveNode(mUpdates[i]);
                    if (add && mUpdates[i] is IStateValidator c)
                        player.ValidateState(c);
#endif
                }
            }
            else
            {
                State = stat == NodeState.Success ? NodeState.Success : NodeState.Failed;
            }
        }

    }

    /// <summary>
    /// 子行为树根节点
    /// </summary>
    public abstract partial class SubExecutableRoot : ActionNode, IExecutableParent
    {
        ExecutableEntry[] mChildren;
        public int ChildCount => mChildren == null ? 0 : mChildren.Length;
        public ExecutableEntry GetChild(int index) { return mChildren[index]; }

        internal override void InitializeSelf(CreateBehaviourTreeContext context)
        {
            base.InitializeSelf(context);
            mChildren = context.childrenBuffer.Count > 0 ? context.childrenBuffer.ToArray() : null;
        }
    }
}
